package com.bm.service.Impl;

import com.bm.enums.ModifyType;
import com.bm.enums.OrderStatus;
import com.bm.exception.BusinessException;
import com.bm.exception.ExceptionCode;
import com.bm.model.Item;
import com.bm.model.Order;
import com.bm.model.OrderModification;
import com.bm.service.IEditService;
import com.bm.service.IOrderRepository;
import com.bm.util.ItemUtil;
import com.bm.util.LocalDateTimeUtil;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

public class EditServiceImpl implements IEditService {
    private final IOrderRepository repository;

    public EditServiceImpl(IOrderRepository repository) {
        this.repository = repository;
    }
    public Order modifyOrder(String orderId, ModifyType request,
                             List<Item> itemsToAdd, List<Item> itemsToRemove,
                             Item itemToUpdate, int newQuantity) {
        // 1. 检查订单是否存在
        Order order = repository.findById(orderId);
        if (order == null) {
            throw new BusinessException(ExceptionCode.ORDER_NOT_FOUND);
        }

        // 2. 检查订单状态
        if (order.getStatus() == OrderStatus.PAID) {
            throw new BusinessException(ExceptionCode.MODIFY_FORBIDDEN);
        }

        // 3. 处理不同类型的修改
        OrderModification modification = new OrderModification(orderId);
        modification.setOriginalTotalPrice(order.getTotalPrice());
        modification.setModificationTime(LocalDateTime.now());

        switch (request) {
            case FULL_REPLACE:
                handleFullReplace(order, itemsToAdd, modification);
                break;
            case PARTIAL_MODIFY:
                handlePartialModification(order, itemsToAdd, itemsToRemove, itemToUpdate, newQuantity, modification);
                break;
            default:
                throw new IllegalArgumentException("Invalid modify type");
        }

        // 4. 生成修改差异单
        generateModificationSheet(order, modification);

        // 5. 商家审批
        if (approveModification(order)) {
            // 审批通过
            updateOrderStatus(order, OrderStatus.CREATED);
            executeModification(order, modification);
            generateOperationLog(order, modification, "pass！");
        } else {
            // 审批未通过
            generateOperationLog(order, modification, "Modification not approved");
        }

        return order;
    }

    private void generateOperationLog(Order order, OrderModification modification, String message) {
        System.out.println("Operation Log: " + message);
        System.out.println("Order ID: " + order.getOrderId());
        System.out.println("Modification Details: " + modification);
        System.out.println("Timestamp: " + LocalDateTimeUtil.getTimestamp(LocalDateTime.now()));
    }

    private void executeModification(Order order, OrderModification modification) {
        order.setTotalPrice(modification.getNewTotalPrice());
        order.setCreateTime(modification.getModificationTime());
        repository.save(order);
    }

    private void updateOrderStatus(Order order, OrderStatus status) {
        order.setStatus(status);
        repository.updateStatus(order.getOrderId(), status);
    }

    private boolean approveModification(Order order) {
        return true; // 假设审批通过
    }

    private void handleFullReplace(Order order, List<Item> newItems, OrderModification modification) {
        List<Item> originalItems = new ArrayList<>(order.getItems());
        order.setItems(newItems);
        modification.setAddedItems(newItems);
        modification.setRemovedItems(originalItems);
        validateItems(newItems);
    }

    private void handlePartialModification(Order order, List<Item> itemsToAdd, List<Item> itemsToRemove, Item itemToUpdate, int newQuantity, OrderModification modification) {
        if (itemsToAdd != null && !itemsToAdd.isEmpty()) {
            validateItems(itemsToAdd);
            modification.setAddedItems(itemsToAdd);
            order.getItems().addAll(itemsToAdd);
        }

        if (itemsToRemove != null && !itemsToRemove.isEmpty()) {
            modification.setRemovedItems(itemsToRemove);
            order.getItems().removeAll(itemsToRemove);
        }

        if (itemToUpdate != null) {
            Item existingItem = order.getItems().stream()
                    .filter(item -> item.getId().equals(itemToUpdate.getId()))
                    .findFirst().orElse(null);
            if (existingItem != null) {
                modification.addUpdatedItem(itemToUpdate.getId(), newQuantity);
                existingItem.setQuantity(newQuantity);
            }
        }
    }

    private void generateModificationSheet(Order order, OrderModification modification) {
        double newTotalPrice = order.getItems().stream()
                .mapToDouble(item -> item.getPrice() * item.getQuantity())
                .sum();
        modification.setNewTotalPrice(newTotalPrice);

        double discountChange = modification.getOriginalTotalPrice() - newTotalPrice;
        modification.setDiscountChange(discountChange);

        System.out.println("Modification Sheet: " + modification);
    }

    private void validateItems(List<Item> items) {
        for (Item item : items) {
            Item itemInfo = ItemUtil.getItemInfo(item.getId());
            if (itemInfo == null) {
                throw new BusinessException(ExceptionCode.ITEM_INVALID);
            }
        }
    }
}